package eteam.aps.systemservice.bll;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import eteam.aps.common.exceptions.BusinessException;
import eteam.aps.common.helper.Helper;
import eteam.aps.systeminterface.model.dto.FlowOrgDto;
import eteam.aps.systeminterface.model.dto.OrgDto;
import eteam.aps.systeminterface.model.dto.VerifyTokenDto;
import eteam.aps.systeminterface.model.entity.OrgEntity;
import eteam.aps.systeminterface.model.enums.OrgTypeEnum;
import eteam.aps.systeminterface.model.enums.StateEnum;
import eteam.aps.systeminterface.model.enums.WhetherEnum;
import eteam.aps.systemservice.dal.OrgDal;
import eteam.aps.systemservice.model.mapper.IOrgMapper;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 机构相关业务
 */
@Service
public class OrgBll {
    @Autowired
    private OrgDal orgDal;

    /**
     * 获取机构树（包含公司，部门，班组）
     *
     * @return
     */
    public List<OrgEntity> getOrgTree() throws Exception {
        List<OrgEntity> tmpOrgList = orgDal.getOrgList();
        List<OrgEntity> rootList = tmpOrgList.stream()
                .filter(p -> StrUtil.isEmpty(p.getFaboveid()))
                .sorted(Comparator.comparing(OrgEntity::getForder))
                .collect(Collectors.toList());
        rootList.forEach(p -> setChildren(p, tmpOrgList));
        return rootList;
    }

    private void setChildren(OrgEntity org, List<OrgEntity> list) {
        List<OrgEntity> tmpList = list.stream().filter(q -> org.getForgid().equals(q.getFaboveid())).sorted(Comparator.comparing(OrgEntity::getForder)).collect(Collectors.toList());
        org.setChildren(tmpList);
        org.setHaschildren(tmpList.stream().count() > 0);
        org.setIsleaf(!org.getHaschildren());
        for (OrgEntity item : org.getChildren()) {
            setChildren(item, list);
        }
    }

    /**
     * 根据机构ID获取下级机构列表
     *
     * @param orgId: 机构ID
     * @return
     */
    public List<OrgEntity> getOrgList(String orgId) throws Exception {
        QueryWrapper<OrgEntity> wrapper = new QueryWrapper<OrgEntity>();
        wrapper.eq("State", StateEnum.Enable.getValue());
        if (StrUtil.isEmpty(orgId)) {
            wrapper.eq("FUnitTypeId", OrgTypeEnum.Org.getValue())
                    .and(i -> i.eq("FAboveId", "").or().isNull("FAboveId"));
        } else {
            wrapper.eq("FAboveId", orgId);
        }
        wrapper.orderByAsc("FOrder");
        return orgDal.getOrgList(wrapper);
    }

    /**
     * 搜索机构列表
     *
     * @param keyword
     * @return
     */
    public List<OrgEntity> searchOrgList(String keyword) throws Exception {
        QueryWrapper<OrgEntity> wrapper = new QueryWrapper<OrgEntity>();
        wrapper.eq("State", StateEnum.Enable.getValue());
        if (StringUtils.isNotBlank(keyword)) {
            wrapper.and(i -> i.like("FCode", keyword).or().like("FName", keyword));
        }
        wrapper.orderByAsc("FInsideCode");
        return orgDal.getOrgList(wrapper);
    }

    /**
     * 创建机构
     *
     * @param orgDto: 请求参数
     * @throws Exception
     */
    public OrgEntity createOrg(VerifyTokenDto tokenDto, OrgDto orgDto) throws Exception {
        if (StrUtil.isEmpty(orgDto.getFcode())) {
            throw new BusinessException("编号不存在");
        }
        if (StrUtil.isEmpty(orgDto.getFaboveid())) {
            throw new BusinessException("上级机构不存在");
        }
        OrgEntity tmpPOrg = orgDal.getById(orgDto.getFaboveid());
        if (Helper.checkObjAllFieldsIsNull(tmpPOrg)) {
            throw new BusinessException("上级机构不存在");
        }
        OrgEntity orgEntity = IOrgMapper.INSTANCE.toEntity(orgDto);
        orgEntity.setForgid(Helper.GetId());
        orgEntity.setFinsidecode(tmpPOrg.getFinsidecode() + "|" + orgEntity.getFcode());
        //若自身为机构，则所属机构为自身ID，否则获取上级节点所属机构ID
        orgEntity.setFmentorgid(orgEntity.getFunittypeid().equals(OrgTypeEnum.Org.getValue()) ? orgEntity.getForgid() : tmpPOrg.getFmentorgid());
        orgEntity.setFisdept(orgEntity.getFunittypeid().equals(OrgTypeEnum.Org.getValue()) ? WhetherEnum.No.getValue() : WhetherEnum.Yes.getValue());
        orgEntity.setFrecorder(tokenDto.getFuserid());
        orgEntity.setFrecordername(tokenDto.getFfullname());
        orgEntity.setFrecordtime(DateUtil.date());
        int count = orgDal.insertOrg(orgEntity);
        if (count < 1) {
            throw new BusinessException("创建机构失败");
        }
        return orgDal.getById(orgEntity.getForgid());
    }

    /**
     * 更新机构
     *
     * @param orgDto: 请求参数
     * @throws Exception
     */
    public OrgEntity updateOrg(VerifyTokenDto tokenDto, OrgDto orgDto) throws Exception {
        if (StrUtil.isEmpty(orgDto.getFcode())) {
            throw new Exception("编号不存在");
        }
        if (StrUtil.isEmpty(orgDto.getFaboveid())) {
            throw new BusinessException("上级机构不存在");
        }
        OrgEntity tmpPOrg = orgDal.getById(orgDto.getFaboveid());
        if (Helper.checkObjAllFieldsIsNull(tmpPOrg)) {
            throw new BusinessException("上级机构不存在");
        }
        OrgEntity orgEntity = IOrgMapper.INSTANCE.toEntity(orgDto);
        orgEntity.setFinsidecode(tmpPOrg.getFinsidecode() + "|" + orgEntity.getFcode());
        //若自身为机构，则所属机构为自身ID，否则获取上级节点所属机构ID
        orgEntity.setFmentorgid(orgEntity.getFunittypeid().equals(OrgTypeEnum.Org.getValue()) ? orgEntity.getForgid() : tmpPOrg.getFmentorgid());
        orgEntity.setFisdept(orgEntity.getFunittypeid().equals(OrgTypeEnum.Org.getValue()) ? WhetherEnum.No.getValue() : WhetherEnum.Yes.getValue());
        orgEntity.setFlastmodifier(tokenDto.getFuserid());
        orgEntity.setFlastmodifiername(tokenDto.getFfullname());
        orgEntity.setFlastmodifytime(DateUtil.date());
        int count = orgDal.updateOrg(orgEntity);
        if (count < 1) {
            throw new BusinessException("更新机构失败");
        }
        return orgDal.getById(orgEntity.getForgid());
    }

    /**
     * 删除机构
     *
     * @param orgId: 机构ID
     * @throws Exception
     */
    public void deleteOrg(String orgId) throws Exception {
        if (StrUtil.isEmpty(orgId)) {
            throw new BusinessException("机构ID不存在");
        }
        Integer childCount = orgDal.getChildrenCount(orgId);
        if (childCount > 0) {
            throw new BusinessException("存在子节点，不允许删除");
        }
        OrgEntity retObj = orgDal.getById(orgId);
        if (Objects.isNull(retObj)) {
            throw new BusinessException("机构不存在");
        }
        if (StringUtils.isEmpty(retObj.getFaboveid())) {
            throw new BusinessException("顶级机构，不允许删除");
        }
        OrgEntity tmpObj = new OrgEntity();
        tmpObj.setForgid(orgId);
        tmpObj.setFcode(StrUtil.format("{}_{}", retObj.getFcode(), System.currentTimeMillis()));
        tmpObj.setFinsidecode(StrUtil.format("{}_{}", retObj.getFinsidecode(), System.currentTimeMillis()));
        tmpObj.setState(StateEnum.Delete.getValue());
        int count = orgDal.updateOrg(tmpObj);
        if (count < 1) {
            throw new BusinessException("删除机构失败");
        }
    }

    /**
     * 获取上级机构Id
     *
     * @param orgId: 当前机构Id
     * @return: 上级机构Id
     */
    public String getAboveOrgId(String orgId) {
        OrgEntity tmpOrg = orgDal.getById(orgId);
        if (Helper.checkObjAllFieldsIsNull(tmpOrg)) {
            return "";
        } else {
            return tmpOrg.getFaboveid();
        }
    }

    /**
     * 获取上级机构对象
     *
     * @param orgId: 当前机构Id
     * @return: 上级机构对象
     */
    public FlowOrgDto getAboveOrg(String orgId) {
        OrgEntity tmpOrg = orgDal.getById(orgId);
        if (Helper.checkObjAllFieldsIsNull(tmpOrg)) {
            return null;
        } else {
            tmpOrg = orgDal.getById(tmpOrg.getFaboveid());
            if (Helper.checkObjAllFieldsIsNull(tmpOrg)) {
                return null;
            }
            FlowOrgDto retObj = new FlowOrgDto();
            retObj.setOrgid(tmpOrg.getForgid());
            retObj.setOrgname(tmpOrg.getFname());
            retObj.setParentorgid(tmpOrg.getFaboveid());
            retObj.setOrgtype(tmpOrg.getFunittypeid());
            retObj.setDeleted(tmpOrg.getState().equals(StateEnum.Delete.getValue()));
            return retObj;
        }
    }

    /**
     * 通过机构名称获取机构Id
     *
     * @param orgName: 机构名称
     * @return: 机构ID
     */
    public String getOrgIdByName(String orgName) {
        OrgEntity tmpOrg = orgDal.getByName(orgName);
        if (Helper.checkObjAllFieldsIsNull(tmpOrg)) {
            return "";
        } else {
            return tmpOrg.getForgid();
        }
    }

    /**
     * 通过机构名称获取机构信息【模糊查找】
     *
     * @param orgName: 机构名称
     * @return: 机构列表
     */
    public List<FlowOrgDto> getOrgListByName(String orgName) {
        List<OrgEntity> tmpList = orgDal.getListByName(orgName);
        List<FlowOrgDto> retObj = new ArrayList<>();
        if (ArrayUtil.hasEmpty(tmpList)) {
            return retObj;
        } else {
            for (OrgEntity tmpOrg : tmpList) {
                FlowOrgDto tmpObj = new FlowOrgDto();
                tmpObj.setOrgid(tmpOrg.getForgid());
                tmpObj.setOrgname(tmpOrg.getFname());
                tmpObj.setParentorgid(tmpOrg.getFaboveid());
                tmpObj.setOrgtype(tmpOrg.getFunittypeid());
                tmpObj.setDeleted(tmpOrg.getState().equals(StateEnum.Delete.getValue()));
                retObj.add(tmpObj);
            }
            return retObj;
        }
    }

    /**
     * 通过机构名称获取机构信息
     *
     * @param orgName: 机构名称
     * @return: 机构信息
     */
    public FlowOrgDto getOrgByName(String orgName) {
        OrgEntity tmpOrg = orgDal.getByName(orgName);
        if (Objects.isNull(tmpOrg)) {
            return null;
        } else {
            FlowOrgDto retObj = new FlowOrgDto();
            retObj.setOrgid(tmpOrg.getForgid());
            retObj.setOrgname(tmpOrg.getFname());
            retObj.setParentorgid(tmpOrg.getFaboveid());
            retObj.setOrgtype(tmpOrg.getFunittypeid());
            retObj.setDeleted(tmpOrg.getState().equals(StateEnum.Delete.getValue()));
            return retObj;
        }
    }

    /**
     * 通过机构Id获取机构信息
     *
     * @param orgId: 机构Id
     * @return: 机构信息
     */
    public FlowOrgDto getOrgById(String orgId) {
        OrgEntity tmpOrg = orgDal.getById(orgId);
        if (Objects.isNull(tmpOrg)) {
            return null;
        } else {
            FlowOrgDto retObj = new FlowOrgDto();
            retObj.setOrgid(tmpOrg.getForgid());
            retObj.setOrgname(tmpOrg.getFname());
            retObj.setParentorgid(tmpOrg.getFaboveid());
            retObj.setOrgtype(tmpOrg.getFunittypeid());
            retObj.setDeleted(tmpOrg.getState().equals(StateEnum.Delete.getValue()));
            return retObj;
        }
    }
}
